(function ($) { $.widget('ui.stars', { options: { inputType: 'radio', // [radio|select] split: 0, // decrease number of stars by splitting each star into pieces [2|3|4|...] disabled: false, // set to [true] to make the stars initially disabled cancelTitle: 'Cancel Rating', cancelValue: 0, // default value of Cancel btn. cancelShow: true, disableValue: true, // set to [false] to not disable the hidden input when Cancel btn is clicked, so the value will present in POST data. oneVoteOnly: false, showTitles: false, captionEl: null, // jQuery object - target for text captions callback: null, // function(ui, type, value, event) /* * CSS classes */ starWidth: 16, // width of the star image cancelClass: 'ui-stars-cancel', starClass: 'ui-stars-star', starOnClass: 'ui-stars-star-on', starHoverClass: 'ui-stars-star-hover', starDisabledClass: 'ui-stars-star-disabled', cancelHoverClass: 'ui-stars-cancel-hover', cancelDisabledClass: 'ui-stars-cancel-disabled' }, _create: function () { var self = this, o = this.options, starId = 0; this.element.data('former.stars', this.element.html()); o.isSelect = o.inputType == 'select'; this.$form = $(this.element).closest('form'); this.$selec = o.isSelect ? $('select', this.element) : null; this.$rboxs = o.isSelect ? $('option', this.$selec) : $(':radio', this.element); /* * Map all inputs from $rboxs array to Stars elements */ this.$stars = this.$rboxs.map(function (i) { var el = { value: this.value, title: (o.isSelect ? this.text : this.title) || this.value, isDefault: (o.isSelect && this.defaultSelected) || this.defaultChecked }; if (i == 0) { o.split = typeof o.split != 'number' ? 0 : o.split; o.val2id = []; o.id2val = []; o.id2title = []; o.name = o.isSelect ? self.$selec.get(0).name : this.name; o.disabled = o.disabled || (o.isSelect ? $(self.$selec).attr('disabled') : $(this).attr('disabled')); } /* * Consider it as a Cancel button? */ if (el.value == o.cancelValue) { o.cancelTitle = el.title; return null; } o.val2id[el.value] = starId; o.id2val[starId] = el.value; o.id2title[starId] = el.title; if (el.isDefault) { o.checked = starId; o.value = o.defaultValue = el.value; o.title = el.title; } var $s = $('
').addClass(o.starClass); var $a = $('').attr('title', o.showTitles ? el.title : '').text(el.value); /* * Prepare division settings */ if (o.split) { var oddeven = (starId % o.split); var stwidth = Math.floor(o.starWidth / o.split); $s.width(stwidth); $a.css('margin-left', '-' + (oddeven * stwidth) + 'px'); } starId++; return $s.append($a).get(0); }); /* * How many Stars? */ o.items = starId; /* * Remove old content */ o.isSelect ? this.$selec.remove() : this.$rboxs.remove(); /* * Append Stars interface */ this.$cancel = $('
').addClass(o.cancelClass).append($('').attr('title', o.showTitles ? o.cancelTitle : '').text(o.cancelValue)); o.cancelShow &= !o.disabled && !o.oneVoteOnly; o.cancelShow && this.element.append(this.$cancel); this.element.append(this.$stars); /* * Initial selection */ if (o.checked === undefined) { o.checked = -1; o.value = o.defaultValue = o.cancelValue; o.title = ''; } /* * The only FORM element, that has been linked to the stars control. The value field is updated on each Star click event */ this.$value = $(""); this.element.append(this.$value); /* * Attach stars event handler */ this.$stars.bind('click.stars', function (e) { if (!o.forceSelect && o.disabled) return false; var i = self.$stars.index(this); o.checked = i; o.value = o.id2val[i]; o.title = o.id2title[i]; self.$value.attr({ disabled: o.disabled ? 'disabled' : '', value: o.value }); fillTo(i, false); self._disableCancel(); !o.forceSelect && self.callback(e, 'star'); }) .bind('mouseover.stars', function () { if (o.disabled) return false; var i = self.$stars.index(this); fillTo(i, true); }) .bind('mouseout.stars', function () { if (o.disabled) return false; fillTo(self.options.checked, false); }); /* * Attach cancel event handler */ this.$cancel.bind('click.stars', function (e) { if (!o.forceSelect && (o.disabled || o.value == o.cancelValue)) return false; o.checked = -1; o.value = o.cancelValue; o.title = ''; self.$value.val(o.value); o.disableValue && self.$value.attr({ disabled: 'disabled' }); fillNone(); self._disableCancel(); !o.forceSelect && self.callback(e, 'cancel'); }) .bind('mouseover.stars', function () { if (self._disableCancel()) return false; self.$cancel.addClass(o.cancelHoverClass); fillNone(); self._showCap(o.cancelTitle); }) .bind('mouseout.stars', function () { if (self._disableCancel()) return false; self.$cancel.removeClass(o.cancelHoverClass); self.$stars.triggerHandler('mouseout.stars'); }); /* * Attach onReset event handler to the parent FORM */ this.$form.bind('reset.stars', function () { !o.disabled && self.select(o.defaultValue); }); /* * Clean up to avoid memory leaks in certain versions of IE 6 */ $(window).unload(function () { self.$cancel.unbind('.stars'); self.$stars.unbind('.stars'); self.$form.unbind('.stars'); self.$selec = self.$rboxs = self.$stars = self.$value = self.$cancel = self.$form = null; }); /* * Star selection helpers */ function fillTo(index, hover) { if (index != -1) { var addClass = hover ? o.starHoverClass : o.starOnClass; var remClass = hover ? o.starOnClass : o.starHoverClass; self.$stars.eq(index).prevAll('.' + o.starClass).addBack().removeClass(remClass).addClass(addClass); self.$stars.eq(index).nextAll('.' + o.starClass).removeClass(o.starHoverClass + ' ' + o.starOnClass); self._showCap(o.id2title[index]); } else fillNone(); }; function fillNone() { self.$stars.removeClass(o.starOnClass + ' ' + o.starHoverClass); self._showCap(''); }; /* * Finally, set up the Stars */ this.select(o.value); o.disabled && this.disable(); }, /* * Private functions */ _disableCancel: function () { var o = this.options, disabled = o.disabled || o.oneVoteOnly || (o.value == o.cancelValue); if (disabled) this.$cancel.removeClass(o.cancelHoverClass).addClass(o.cancelDisabledClass); else this.$cancel.removeClass(o.cancelDisabledClass); this.$cancel.css('opacity', disabled ? 0.5 : 1); return disabled; }, _disableAll: function () { var o = this.options; this._disableCancel(); if (o.disabled) this.$stars.filter('div').addClass(o.starDisabledClass); else this.$stars.filter('div').removeClass(o.starDisabledClass); }, _showCap: function (s) { var o = this.options; if (o.captionEl) o.captionEl.text(s); }, /* * Public functions */ value: function () { return this.options.value; }, select: function (val) { var o = this.options, e = (val == o.cancelValue) ? this.$cancel : this.$stars.eq(o.val2id[val]); o.forceSelect = true; e.triggerHandler('click.stars'); o.forceSelect = false; }, selectID: function (id) { var o = this.options, e = (id == -1) ? this.$cancel : this.$stars.eq(id); o.forceSelect = true; e.triggerHandler('click.stars'); o.forceSelect = false; }, enable: function () { this.options.disabled = false; this._disableAll(); }, disable: function () { this.options.disabled = true; this._disableAll(); }, destroy: function () { this.$form.unbind('.stars'); this.$cancel.unbind('.stars').remove(); this.$stars.unbind('.stars').remove(); this.$value.remove(); this.element.unbind('.stars').html(this.element.data('former.stars')).removeData('stars'); return this; }, callback: function (e, type) { var o = this.options; o.callback && o.callback(this, type, o.value, e); o.oneVoteOnly && !o.disabled && this.disable(); } }); $.extend($.ui.stars, { version: '3.0.1' }); })(clickd_jquery);/* * jQuery timepicker addon * By: Trent Richardson [http://trentrichardson.com] * Version 0.9.5 * Last Modified: 05/25/2011 * * Copyright 2011 Trent Richardson * Dual licensed under the MIT and GPL licenses. * http://trentrichardson.com/Impromptu/GPL-LICENSE.txt * http://trentrichardson.com/Impromptu/MIT-LICENSE.txt * * HERES THE CSS: * .ui-timepicker-div .ui-widget-header{ margin-bottom: 8px; } * .ui-timepicker-div dl{ text-align: left; } * .ui-timepicker-div dl dt{ height: 25px; } * .ui-timepicker-div dl dd{ margin: -25px 10px 10px 65px; } * .ui-timepicker-div td { font-size: 90%; } */ (function ($) { $.extend($.ui, { timepicker: { version: "0.9.5" } }); /* Time picker manager. Use the singleton instance of this class, $.timepicker, to interact with the time picker. Settings for (groups of) time pickers are maintained in an instance object, allowing multiple different settings on the same page. */ function Timepicker() { this.regional = []; // Available regional settings, indexed by language code this.regional[''] = { // Default regional settings currentText: 'Now', closeText: 'Done', ampm: false, timeFormat: 'hh:mm tt', timeOnlyTitle: 'Choose Time', timeText: 'Time', hourText: 'Hour', minuteText: 'Minute', secondText: 'Second', timezoneText: 'Time Zone' }; this._defaults = { // Global defaults for all the datetime picker instances showButtonPanel: true, timeOnly: false, showHour: true, showMinute: true, showSecond: false, showTimezone: false, showTime: true, stepHour: 0.05, stepMinute: 0.05, stepSecond: 0.05, hour: 0, minute: 0, second: 0, timezone: '+0000', hourMin: 0, minuteMin: 0, secondMin: 0, hourMax: 23, minuteMax: 59, secondMax: 59, minDateTime: null, maxDateTime: null, hourGrid: 0, minuteGrid: 0, secondGrid: 0, alwaysSetTime: true, separator: ' ', altFieldTimeOnly: true, showTimepicker: true, timezoneList: ["-1100", "-1000", "-0900", "-0800", "-0700", "-0600", "-0500", "-0400", "-0300", "-0200", "-0100", "+0000", "+0100", "+0200", "+0300", "+0400", "+0500", "+0600", "+0700", "+0800", "+0900", "+1000", "+1100", "+1200"] }; $.extend(this._defaults, this.regional['']); } $.extend(Timepicker.prototype, { $input: null, $altInput: null, $timeObj: null, inst: null, hour_slider: null, minute_slider: null, second_slider: null, timezone_select: null, hour: 0, minute: 0, second: 0, timezone: '+0000', hourMinOriginal: null, minuteMinOriginal: null, secondMinOriginal: null, hourMaxOriginal: null, minuteMaxOriginal: null, secondMaxOriginal: null, ampm: '', formattedDate: '', formattedTime: '', formattedDateTime: '', timezoneList: ["-1100", "-1000", "-0900", "-0800", "-0700", "-0600", "-0500", "-0400", "-0300", "-0200", "-0100", "+0000", "+0100", "+0200", "+0300", "+0400", "+0500", "+0600", "+0700", "+0800", "+0900", "+1000", "+1100", "+1200"], /* Override the default settings for all instances of the time picker. @param settings object - the new settings to use as defaults (anonymous object) @return the manager object */ setDefaults: function (settings) { extendRemove(this._defaults, settings || {}); return this; }, //######################################################################## // Create a new Timepicker instance //######################################################################## _newInst: function ($input, o) { var tp_inst = new Timepicker(), inlineSettings = {}; for (var attrName in this._defaults) { var attrValue = $input.attr('time:' + attrName); if (attrValue) { try { inlineSettings[attrName] = eval(attrValue); } catch (err) { inlineSettings[attrName] = attrValue; } } } tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, o, { beforeShow: function (input, dp_inst) { if ($.isFunction(o.beforeShow)) o.beforeShow(input, dp_inst, tp_inst); }, onChangeMonthYear: function (year, month, dp_inst) { // Update the time as well : this prevents the time from disappearing from the $input field. tp_inst._updateDateTime(dp_inst); if ($.isFunction(o.onChangeMonthYear)) o.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst); }, onClose: function (dateText, dp_inst) { if (tp_inst.timeDefined === true && $input.val() != '') tp_inst._updateDateTime(dp_inst); if ($.isFunction(o.onClose)) o.onClose.call($input[0], dateText, dp_inst, tp_inst); }, timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker'); }); tp_inst.hour = tp_inst._defaults.hour; tp_inst.minute = tp_inst._defaults.minute; tp_inst.second = tp_inst._defaults.second; tp_inst.ampm = ''; tp_inst.$input = $input; if (o.altField) tp_inst.$altInput = $(o.altField) .css({ cursor: 'pointer' }) .focus(function () { $input.trigger("focus"); }); // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime.. if (tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date) tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime()); if (tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date) tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime()); if (tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date) tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime()); if (tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date) tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime()); return tp_inst; }, //######################################################################## // add our sliders to the calendar //######################################################################## _addTimePicker: function (dp_inst) { var currDT = (this.$altInput && this._defaults.altFieldTimeOnly) ? this.$input.val() + ' ' + this.$altInput.val() : this.$input.val(); this.timeDefined = this._parseTime(currDT); this._limitMinMaxDateTime(dp_inst, false); this._injectTimePicker(); }, //######################################################################## // parse the time string from input value or _setTime //######################################################################## _parseTime: function (timeString, withDate) { var regstr = this._defaults.timeFormat.toString() .replace(/h{1,2}/ig, '(\\d?\\d)') .replace(/m{1,2}/ig, '(\\d?\\d)') .replace(/s{1,2}/ig, '(\\d?\\d)') .replace(/t{1,2}/ig, '(am|pm|a|p)?') .replace(/z{1}/ig, '((\\+|-)\\d\\d\\d\\d)?') .replace(/\s/g, '\\s?') + '$', order = this._getFormatPositions(), treg; if (!this.inst) this.inst = $.datepicker._getInst(this.$input[0]); if (withDate || !this._defaults.timeOnly) { // the time should come after x number of characters and a space. // x = at least the length of text specified by the date format var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat'); // escape special regex characters in the seperator var specials = new RegExp("[.*+?|()\\[\\]{}\\\\]", "g"); regstr = '.{' + dp_dateFormat.length + ',}' + this._defaults.separator.replace(specials, "\\$&") + regstr; } treg = timeString.match(new RegExp(regstr, 'i')); if (treg) { if (order.t !== -1) this.ampm = ((treg[order.t] === undefined || treg[order.t].length === 0) ? '' : (treg[order.t].charAt(0).toUpperCase() == 'A') ? 'AM' : 'PM').toUpperCase(); if (order.h !== -1) { if (this.ampm == 'AM' && treg[order.h] == '12') this.hour = 0; // 12am = 0 hour else if (this.ampm == 'PM' && treg[order.h] != '12') this.hour = (parseFloat(treg[order.h]) + 12).toFixed(0); // 12pm = 12 hour, any other pm = hour + 12 else this.hour = Number(treg[order.h]); } if (order.m !== -1) this.minute = Number(treg[order.m]); if (order.s !== -1) this.second = Number(treg[order.s]); if (order.z !== -1) this.timezone = treg[order.z]; return true; } return false; }, //######################################################################## // figure out position of time elements.. cause js cant do named captures //######################################################################## _getFormatPositions: function () { var finds = this._defaults.timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|t{1,2}|z)/g), orders = { h: -1, m: -1, s: -1, t: -1, z: -1 }; if (finds) for (var i = 0; i < finds.length; i++) if (orders[finds[i].toString().charAt(0)] == -1) orders[finds[i].toString().charAt(0)] = i + 1; return orders; }, //######################################################################## // generate and inject html for timepicker into ui datepicker //######################################################################## _injectTimePicker: function () { var $dp = this.inst.dpDiv, o = this._defaults, tp_inst = this, // Added by Peter Medeiros: // - Figure out what the hour/minute/second max should be based on the step values. // - Example: if stepMinute is 15, then minMax is 45. hourMax = (o.hourMax - (o.hourMax % o.stepHour)).toFixed(0), minMax = (o.minuteMax - (o.minuteMax % o.stepMinute)).toFixed(0), secMax = (o.secondMax - (o.secondMax % o.stepSecond)).toFixed(0), dp_id = this.inst.id.toString().replace(/([^A-Za-z0-9_])/g, ''); // Prevent displaying twice //if ($dp.find("div#ui-timepicker-div-"+ dp_id).length === 0) { if ($dp.find("div#ui-timepicker-div-" + dp_id).length === 0 && o.showTimepicker) { var noDisplay = ' style="display:none;"', html = '
' + '
' + o.timeText + '
' + '
' + '
' + o.hourText + '
', hourGridSize = 0, minuteGridSize = 0, secondGridSize = 0, size; if (o.showHour && o.hourGrid > 0) { html += '
' + '
' + '
'; for (var h = o.hourMin; h < hourMax; h += o.hourGrid) { hourGridSize++; var tmph = (o.ampm && h > 12) ? h - 12 : h; if (tmph < 10) tmph = '0' + tmph; if (o.ampm) { if (h == 0) tmph = 12 + 'a'; else if (h < 12) tmph += 'a'; else tmph += 'p'; } html += ''; } html += '
' + tmph + '
' + '
'; } else html += '
'; html += '
' + o.minuteText + '
'; if (o.showMinute && o.minuteGrid > 0) { html += '
' + '
' + '
'; for (var m = o.minuteMin; m < minMax; m += o.minuteGrid) { minuteGridSize++; html += ''; } html += '
' + ((m < 10) ? '0' : '') + m + '
' + '
'; } else html += '
'; html += '
' + o.secondText + '
'; if (o.showSecond && o.secondGrid > 0) { html += '
' + '
' + '
'; for (var s = o.secondMin; s < secMax; s += o.secondGrid) { secondGridSize++; html += ''; } html += '
' + ((s < 10) ? '0' : '') + s + '
' + '
'; } else html += '
'; html += '
' + o.timezoneText + '
'; html += '
'; html += '
'; $tp = $(html); // if we only want time picker... if (o.timeOnly === true) { $tp.prepend( '
' + '
' + o.timeOnlyTitle + '
' + '
'); $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide(); } this.hour_slider = $tp.find('#ui_tpicker_hour_' + dp_id).slider({ orientation: "horizontal", value: this.hour, min: o.hourMin, max: hourMax, step: o.stepHour, slide: function (event, ui) { tp_inst.hour_slider.slider("option", "value", ui.value); tp_inst._onTimeChange(); } }); // Updated by Peter Medeiros: // - Pass in Event and UI instance into slide function this.minute_slider = $tp.find('#ui_tpicker_minute_' + dp_id).slider({ orientation: "horizontal", value: this.minute, min: o.minuteMin, max: minMax, step: o.stepMinute, slide: function (event, ui) { // update the global minute slider instance value with the current slider value tp_inst.minute_slider.slider("option", "value", ui.value); tp_inst._onTimeChange(); } }); this.second_slider = $tp.find('#ui_tpicker_second_' + dp_id).slider({ orientation: "horizontal", value: this.second, min: o.secondMin, max: secMax, step: o.stepSecond, slide: function (event, ui) { tp_inst.second_slider.slider("option", "value", ui.value); tp_inst._onTimeChange(); } }); this.timezone_select = $tp.find('#ui_tpicker_timezone_' + dp_id).append('').find("select"); $.fn.append.apply(this.timezone_select, $.map(o.timezoneList, function (val, idx) { return $("